import { Stage } from "babylon-lib/base/stage";
import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin";
import HavokPhysics from "@babylonjs/havok";
import '@babylonjs/core/Physics/physicsEngineComponent';
import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate";
import { PhysicsViewer } from '@babylonjs/core/Debug/physicsViewer';
import { Vector3 } from "babylon-lib/index";
import { Mesh } from "@babylonjs/core/Meshes/mesh";
import { PhysicsShapeType } from "@babylonjs/core/Physics/v2/IPhysicsEnginePlugin";


class PhysicsManager {

    public static viewer: PhysicsViewer;
    public static readonly staticAggregates: PhysicsAggregate[] = [];

    private static _stage: Stage;

    public static async initialize(stage: Stage): Promise<void> {
        this._stage = stage;
        const havok = await HavokPhysics();
        const plugin = new HavokPlugin(true, havok);
        stage.mainScene.enablePhysics(new Vector3(0, -9.8, 0), plugin);
        this.viewer = new PhysicsViewer(stage.mainScene);
    }

    public static set debug(debug: boolean) {
        this.staticAggregates.forEach(r => {
            debug ? PhysicsManager.viewer.showBody(r.body) : PhysicsManager.viewer.hideBody(r.body);
        });
    }

    public static setStaticAggregateBox(...meshes: Mesh[]): void {
        for (const m of meshes) {
            if (!m.geometry) continue;
            const pa = new PhysicsAggregate(m, PhysicsShapeType.BOX, { mass: 0, friction: 0.7 }, this._stage.mainScene);
            this.staticAggregates.push(pa);
            m.isVisible = false;
            m.isPickable = false;
            m.checkCollisions = false;
        }
    }

}


export { PhysicsManager };